#include "TaskQueue.h"

using std::unique_lock;

TaskQueue::TaskQueue(size_t size) : _size(size), _isWakeup(false) {}

bool TaskQueue::empty()
{
    return _taskQueue.empty();
}

bool TaskQueue::full()
{
    return _taskQueue.size() == _size;
}

void TaskQueue::push(Task &&taskcb)
{
    unique_lock<mutex> lock(_mutex);
    _cond.wait(lock, [this]() { return !full(); });
    _taskQueue.push(std::move(taskcb));
    _cond.notify_one();
}

Task TaskQueue::pop()
{
    unique_lock<mutex> lock(_mutex);
    _cond.wait(lock, [this]() { return !empty() || _isWakeup; });
    if (_isWakeup)
    {
        return nullptr;
    }
    Task taskcb = _taskQueue.front();
    _taskQueue.pop();
    return taskcb;
}

void TaskQueue::wakeup()
{
    _isWakeup = true;
    _cond.notify_all();
}